
#include "IO.h"
#include "BSP_Delay.h"
#include "BSP_Config.h"
#include "Env.h"

#define WG_HIGH		0
#define WG_LOW		1

static const IO_T wgD0 = {(void*)WG_D0_GP, WG_D0_PIN};
static const IO_T wgD1 = {(void*)WG_D1_GP, WG_D1_PIN};

#if 0
static uint32_t wgIdleTime;
static uint32_t wgActiveTime;

static void BSP_WG_Idle(void){
	IO_Set(&wgD0, WG_HIGH);
	IO_Set(&wgD1, WG_HIGH);
}

void BSP_WG_Config(uint32_t activeTime, uint32_t idleTime){
	wgActiveTime = activeTime;
	wgIdleTime = idleTime;
}
#endif
static void BSP_WG_Idle(void){
	IO_Set(&wgD0, WG_HIGH);
	IO_Set(&wgD1, WG_HIGH);
}

void BSP_WG_Init(void){
	IO_Init(&wgD0, IO_Mode_OUT);
	IO_Init(&wgD1, IO_Mode_OUT);
	BSP_WG_Idle();
	//wgIdleTime = 1000;
	//wgActiveTime = 50;
}

void BSP_WG_Set(uint8_t b){
	if(b){
		IO_Set(&wgD1, WG_LOW);
	}
	else{
		IO_Set(&wgD0, WG_LOW);
	}
}
#if 0
void BSP_WG_SendBit(uint8_t b){
	if(b){
		IO_Set(&wgD1, WG_LOW);
	}
	else{
		IO_Set(&wgD0, WG_LOW);
	}
	BSP_Delay_us(wgActiveTime);
	BSP_WG_Idle();
	BSP_Delay_us(wgIdleTime);
}
#endif
/*.................................................................................................................................................................................*/
void WgOneBitOver(void){	
	BSP_Delay_us((envProp.wgPulseWidth[0]*10));
	IO_Set(&wgD1, WG_HIGH);
	IO_Set(&wgD0, WG_HIGH);
	BSP_Delay_us((envProp.wgPulseWidth[1]*100));
}
/*.................................................................................................................................................................................*/
void WgOneBitOver1(void){	
	BSP_Delay_us(50);
	IO_Set(&wgD1, WG_HIGH);
	IO_Set(&wgD0, WG_HIGH);
	BSP_Delay_us(1000);
}
/*.................................................................................................................................................................................*/
void weigand_key(uint8_t key_data)
{
	uint8_t i;
	uint8_t bit_mask=0x80;	
	__disable_irq();

	for (i=0;i < 8; i++){
		if (key_data & bit_mask){ 
			IO_Set(&wgD1, WG_LOW);
		}
		else{
			IO_Set(&wgD0, WG_LOW);
		}	
		WgOneBitOver();
		bit_mask = bit_mask >>1;
	}	
	__enable_irq();
}

/*.................................................................................................................................................................................*/
void WeigandOut(uint8_t wgType,uint8_t *wgData)
{
	uint8_t wgByteCnt,wgBitCntE_O;
	unsigned char bit_mask;
    unsigned char i,j;
    unsigned char e_parity, o_parity;

	__disable_irq();
	
	wgByteCnt = (wgType-2)/8;	wgBitCntE_O = (wgType-2)/2;
	
	if(envProp.wgParityFlag)
	{
		//--------------e_parity 前一半数据的偶检验
		for ( bit_mask = 0x80,e_parity=0,i = 0 ; i < wgBitCntE_O; i++ )
		{
			j = i/8;
			if (wgData[j] & bit_mask) e_parity++;
			bit_mask = bit_mask >> 1;
			if ( bit_mask==0x00 )	bit_mask = 0x80;
		}
		//--------------o_parity 后一半数据的奇检验
		for ( bit_mask = 0x01,o_parity=0,i = 0 ; i < wgBitCntE_O; i++ )
		{
			j = i/8;	j = wgByteCnt-1-j;
			if (wgData[j] & bit_mask) o_parity++;
			bit_mask = bit_mask << 1;
			if ( bit_mask==0x00 )	bit_mask = 0x01;
		}

		e_parity = e_parity & 0x01;
		if (o_parity & 0x01)	o_parity = 0;
		else 					o_parity = 1;
		//--------------send e_parity
		if (e_parity)	IO_Set(&wgD1, WG_LOW);
		else 			IO_Set(&wgD0, WG_LOW);
		
		WgOneBitOver();
	}
	
	//--------------send wgData[i] 从低字节开始发 发字节的高位先	
	for (i=0;i < wgByteCnt; i++)   
	{
		bit_mask =0x80;
		for (j =0; j < 8; j++)
		{	
			if (wgData[i] & bit_mask )	IO_Set(&wgD1, WG_LOW);
			else 						IO_Set(&wgD0, WG_LOW);	
			WgOneBitOver();
			bit_mask = bit_mask >>1;
		}
	}
	
	if(envProp.wgParityFlag)
	{
		//--------------send o_parity
		if (o_parity)	IO_Set(&wgD1, WG_LOW);
		else 			IO_Set(&wgD0, WG_LOW);		
		
		WgOneBitOver();
	}
	
	__enable_irq();
}
/*.................................................................................................................................................................................*/
void WeigandOut1(uint8_t wgType,uint8_t *wgData)
{
	uint8_t wgByteCnt,wgBitCntE_O;
	unsigned char bit_mask;
    unsigned char i,j;
    unsigned char e_parity, o_parity;
	
	//OS_ENTER_CRITICAL();
	
	wgByteCnt = (wgType-2)/8;	wgBitCntE_O = (wgType-2)/2;
	
	//--------------e_parity 前一半数据的偶检验
	for ( bit_mask = 0x80,e_parity=0,i = 0 ; i < wgBitCntE_O; i++ )
	{
		j = i/8;
		if (wgData[j] & bit_mask) e_parity++;
		bit_mask = bit_mask >> 1;
		if ( bit_mask==0x00 )	bit_mask = 0x80;
	}
	//--------------o_parity 后一半数据的奇检验
	for ( bit_mask = 0x01,o_parity=0,i = 0 ; i < wgBitCntE_O; i++ )
	{
		j = i/8;	j = wgByteCnt-1-j;
		if (wgData[j] & bit_mask) o_parity++;
		bit_mask = bit_mask << 1;
		if ( bit_mask==0x00 )	bit_mask = 0x01;
	}

	e_parity = e_parity & 0x01;
	if (o_parity & 0x01)	o_parity = 0;
	else 					o_parity = 1;
	//--------------send e_parity
	if (e_parity)	IO_Set(&wgD1, WG_LOW);
	else 			IO_Set(&wgD0, WG_LOW);
	
	WgOneBitOver1();
	//--------------send wgData[i] 从低字节开始发 发字节的高位先	
	for (i=0;i < wgByteCnt; i++)   
	{
		bit_mask =0x80;
		for (j =0; j < 8; j++)
		{	
			if (wgData[i] & bit_mask )	IO_Set(&wgD1, WG_LOW);
			else 						IO_Set(&wgD0, WG_LOW);	
			WgOneBitOver1();
			bit_mask = bit_mask >>1;
		}
	}
	
	//--------------send o_parity
	if (o_parity)	IO_Set(&wgD1, WG_LOW);
	else 			IO_Set(&wgD0, WG_LOW);		
	
	WgOneBitOver1();
	//OS_EXIT_CRITICAL();
}


